<template>
  <!-- <div class="maintenance-wrapper"> -->
    <el-card class="card-box">
      <div class="header">
        <h2>维修派单管理</h2>
        <div class="stats">
          <el-tag type="danger">待分配: {{ stats.pending }}</el-tag>
          <el-tag type="warning">已分配: {{ stats.assigned }}</el-tag>
          <el-tag type="success">已完成: {{ stats.completed }}</el-tag>
        </div>
      </div>

      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
        <el-tab-pane label="派单处理" name="assign">
          <el-form inline class="filter-bar">
            <el-form-item label="设备ID:">
              <el-select
                v-model="searchParams.serialNumber"
                filterable remote clearable reserve-keyword
                placeholder="请输入设备ID"
                :remote-method="fetchSerialSuggestions"
                :loading="loadingSerialNumbers"
                class="input-short"
              >
                <el-option
                  v-for="item in serialNumberOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="申请人ID:">
              <el-input
                v-model.number="searchParams.applicantId"
                placeholder="请输入申请人ID"
                type="number"
                clearable
                class="input-short"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="loadRequests">搜索</el-button>
              <el-button @click="resetSearch">重置</el-button>
            </el-form-item>
          </el-form>

          <div class="responsive-table-container">
            <table class="custom-table">
              <thead>
                <tr>
                  <th>编号</th>
                  <th>设备ID</th>
                  <th>申请人ID</th>
                  <th>故障描述</th>
                  <th>附件</th>
                  <th>申请时间</th>
                  <th>状态</th>
                  <th>操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="item in pendingAssignments" :key="item.id">
                  <td>{{ item.id }}</td>
                  <td>{{ item.serialNumber }}</td>
                  <td>{{ item.applicantId }}</td>
                  <td class="truncate">{{ item.faultDescription }}</td>
                  <td>
  <template v-if="item.faultImageUrl">
    <template v-if="isImageFile(item.faultImageUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="item.faultImageUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(item.faultImageUrl)"
          />
        </template>
        <img :src="item.faultImageUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="item.faultImageUrl"
        :download="item.faultImageUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(item.faultImageUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
                  <td>{{ item.requestTime }}</td>
                  <td>
                    <el-tag :type="statusTagType(item.status)">
                      {{ item.status }}
                    </el-tag>
                  </td>
                  <td>
                    <div class="action-btns">
                      <el-button
                        :icon="View"
                        circle
                        plain
                        size="small"
                        type="info"
                        @click="showDispatchInfo(item)"
                      />
                      <el-button
                        :icon="Check"
                        circle
                        plain
                        size="small"
                        type="success"
                        :disabled="item.status !== '待分配'"
                        @click="showAssignDialog(item)"
                      />
                    </div>
                  </td>
                </tr>
                <tr v-if="pendingAssignments.length === 0">
                  <td colspan="8" class="text-center py-4">
                    <el-empty description="暂无待派单申请" />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

          <div class="pagination-container">
            <el-pagination
              v-model:current-page="pagination.current"
              v-model:page-size="pagination.size"
              :page-sizes="[3, 5, 7, 10]"
              layout="total, sizes, prev, pager, next, jumper"
              background
              :total="pagination.total"
              @size-change="loadRequests"
              @current-change="loadRequests"
            />
          </div>
        </el-tab-pane>

        <el-tab-pane label="派单记录" name="history">
          <el-form inline class="filter-bar">
            <el-form-item label="设备ID:">
              <el-select
                v-model="historySearchParams.serialNumber"
                filterable remote clearable reserve-keyword
                placeholder="请输入设备ID"
                :remote-method="fetchSerialSuggestions"
                :loading="loadingSerialNumbers"
                class="input-short"
              >
                <el-option
                  v-for="item in serialNumberOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="申请人ID:">
              <el-input
                v-model.number="historySearchParams.applicantId"
                placeholder="请输入申请人ID"
                type="number"
                clearable
                class="input-short"
              />
            </el-form-item>
            <el-form-item label="状态:">
              <el-select
                v-model="historySearchParams.selectedStatus"
                placeholder="请选择状态"
                clearable
                class="input-short"
              >
                <el-option label="已分配" value="已分配" />
                <el-option label="维修完毕" value="维修完毕" />
                <el-option label="已完成" value="已完成" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="loadHistory">搜索</el-button>
              <el-button @click="resetHistorySearch">重置</el-button>
            </el-form-item>
          </el-form>

          <div class="responsive-table-container">
            <table class="custom-table">
              <thead>
                <tr>
                  <th>ID</th>
                  <th>设备ID</th>
                  <th>申请人ID</th>
                  <th>故障描述</th>
                  <th>状态</th>
                  <th>维修师傅ID</th>
                  <th>派单时间</th>
                  <th>操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="item in assignmentHistory" :key="item.id">
                  <td>{{ item.id }}</td>
                  <td>{{ item.serialNumber }}</td>
                  <td>{{ item.applicantId }}</td>
                  <td class="truncate">{{ item.faultDescription }}</td>
                  <td>
                    <el-tag :type="statusTagType(item.status)">
                      {{ item.status }}
                    </el-tag>
                  </td>
                  <td>{{ item.assignedToId || '-' }}</td>
                  <td>{{ item.assignTime || '-' }}</td>
                  <td>
                    <div class="action-btns">
                      <el-button
                        :icon="View"
                        circle
                        plain
                        size="small"
                        type="info"
                        @click="showDispatchInfo(item)"
                      />
                    </div>
                  </td>
                </tr>
                <tr v-if="assignmentHistory.length === 0">
                  <td colspan="8" class="text-center py-4">
                    <el-empty description="暂无派单记录" />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

          <div class="pagination-container">
            <el-pagination
              v-model:current-page="historyPagination.current"
              v-model:page-size="historyPagination.size"
              :page-sizes="[3, 5, 7, 10]"
              layout="total, sizes, prev, pager, next, jumper"
              background
              :total="historyPagination.total"
              @size-change="loadHistory"
              @current-change="loadHistory"
            />
          </div>
        </el-tab-pane>
      </el-tabs>

      <!-- 派单对话框 -->
      <el-dialog 
        v-model="assignDialog.visible" 
        :title="`维修派单 - 申请ID: ${assignForm.requestId}`" 
        width="50%"
      >
        <el-form :model="assignForm" label-width="120px" class="drawer-form">
          <el-form-item label="申请ID">
            <el-input v-model="assignForm.requestId" disabled />
          </el-form-item>
          <el-form-item label="设备ID">
            <el-input v-model="assignForm.serialNumber" disabled />
          </el-form-item>
          <el-form-item label="维修师傅ID" required>
            <el-input-number
              v-model="assignForm.repairerId"
              placeholder="请输入维修师傅ID"
              :min="1"
              :controls="false"
              style="width: 100%"
            />
          </el-form-item>
          <el-form-item>
            <el-button 
              type="primary" 
              @click="assignRepairer"
              class="submit-btn"
            >
              确认派单
            </el-button>
          </el-form-item>
        </el-form>
      </el-dialog>

      <!-- 派单信息对话框 -->
      <el-dialog 
        v-model="infoDialog.visible" 
        :title="`派单信息 - 申请ID: ${currentRequest?.id}`" 
        width="50%"
      >
        <el-descriptions :column="1" border>
          <el-descriptions-item label="维修师傅ID">
            {{ currentRequest?.assignedToId || '未分配' }}
          </el-descriptions-item>
          <el-descriptions-item label="派单时间">
            {{ currentRequest?.assignTime || '未派单' }}
          </el-descriptions-item>
          <el-descriptions-item label="当前状态">
            <el-tag :type="statusTagType(currentRequest?.status || '')">
              {{ currentRequest?.status }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="故障描述">
            {{ currentRequest?.faultDescription }}
          </el-descriptions-item>
          <el-descriptions-item label="附件">
            
  <template v-if="currentRequest?.faultImageUrl">
  <template v-if="isImageFile(currentRequest.faultImageUrl)">
    <el-popover
      placement="left"
      trigger="hover"
      :width="325"
      popper-class="image-popover"
    >
      <template #reference>
        <img
          :src="currentRequest.faultImageUrl"
          class="thumbnail-img"
          alt="缩略图"
          @click.stop="downloadFile(currentRequest.faultImageUrl)"
          style="cursor: pointer;"
        />
      </template>
      <img :src="currentRequest.faultImageUrl" class="preview-img" alt="大图预览" />
    </el-popover>
  </template>
  <template v-else>
    <el-button
      type="primary"
      icon="Download"
      @click="downloadFile(currentRequest.faultImageUrl)"
    >
      点击下载
    </el-button>
  </template>
</template>
<span v-else class="no-attachment">无附件</span>
          </el-descriptions-item>
          <el-descriptions-item label="申请时间">
            {{ currentRequest?.requestTime }}
          </el-descriptions-item>
        </el-descriptions>
      </el-dialog>
    </el-card>
  <!-- </div> -->
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { View, Check } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
import { Download } from '@element-plus/icons-vue'; // 导入 Download 图标组件
interface RepairRequest {
  id: number
  serialNumber: string
  applicantId: number
  faultDescription: string
  faultImageUrl: string
  requestTime: string
  status: string
  assignedToId?: number
  assignTime?: string
  updateTime?: string
}

interface RequestStats {
  pending: number
  assigned: number
  completed: number
}

const activeTab = ref('assign')
const pendingAssignments = ref<RepairRequest[]>([])
const assignmentHistory = ref<RepairRequest[]>([])
const currentRequest = ref<RepairRequest | null>(null)
const serialNumberOptions = ref<string[]>([])
const loadingSerialNumbers = ref(false)

const searchParams = reactive({
  serialNumber: null as string | null,
  applicantId: null as number | null,
  status: '待分配'
})

const historySearchParams = reactive({
  serialNumber: null as string | null,
  applicantId: null as number | null,
  selectedStatus: null as string | null  // 用户选择的单个状态
})

const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
})

const historyPagination = reactive({
  current: 1,
  size: 10,
  total: 0
})

const stats = reactive<RequestStats>({
  pending: 0,
  assigned: 0,
  completed: 0
})

const assignDialog = reactive({
  visible: false
})

const infoDialog = reactive({
  visible: false
})

const assignForm = reactive({
  requestId: null as number | null,
  serialNumber: null as string | null,
  repairerId: null as number | null
})

const fetchSerialSuggestions = async (query: string) => {
  if (query) {
    loadingSerialNumbers.value = true
    try {
      const res = await request<string[]>({
        method: 'GET',
        url: '/device/serial/suggestions',
        params: { keyword: query }
      })
      serialNumberOptions.value = res.data
    } catch {
      ElMessage.error('获取设备序列号失败')
    } finally {
      loadingSerialNumbers.value = false
    }
  } else {
    serialNumberOptions.value = []
  }
}

const loadRequests = async () => {
  try {
    const params: {
      page: number; // pagination.current 通常是 number 类型
      size: number; // pagination.size 通常是 number 类型
      [key: string]: any; // ✨ 添加索引签名，允许通过字符串键访问，值为 any 类型
    } = {
      page: pagination.current,
      size: pagination.size,
      ...searchParams, // 展开 searchParams 的所有属性
    };

    // 遍历 params 对象的所有键
    Object.keys(params).forEach(key => {
      // `params[key]` 现在是类型安全的访问方式，不会再报错 TS7053
      // 检查值是否严格等于 null
      if (params[key] === null) {
        delete params[key]; // 如果是 null，则从 params 对象中删除该属性
      }
    });

    console.log(params); // 打印修改后的 params 对象

    const response = await request({
      method: 'GET',
      url: '/repair/request/list',
      params
    })

    pendingAssignments.value = response.data.records
    pagination.total = response.data.total
    calculateStats()
  } catch (error) {
    ElMessage.error('获取维修申请列表失败')
  }
}

const loadHistory = async () => {
  try {
    // 根据用户是否选择了状态决定查询参数
    let statusArray: string[] | null = null;
    
    if (historySearchParams.selectedStatus) {
      // 用户选择了特定状态，只查询该状态
      statusArray = [historySearchParams.selectedStatus];
    } else {
      // 用户未选择状态，默认查询三个状态
      statusArray = ['已分配', '维修完毕', '已完成'];
    }

  const params: {
    page: number | null;
    size: number | null;
    serialNumber: string | null;
    applicantId: number | null;
    status: string | string[] | null;
    [key: string]: any; // 添加索引签名以解决 TypeScript 错误 TS7053
  } = {
    page: historyPagination.current,
    size: historyPagination.size,
    serialNumber: historySearchParams.serialNumber,
    applicantId: historySearchParams.applicantId,
    status: statusArray
  };

  Object.keys(params).forEach(key => {
  if (params[key] === null || params[key] === undefined || params[key] === '') {
    delete params[key];
  }
});
    

    const response = await request({
      method: 'GET',
      url: '/repair/request/list',
      params,
      paramsSerializer: {
        indexes: null // 处理数组参数
      }
    })

    assignmentHistory.value = response.data.records;
    historyPagination.total = response.data.total;
  } catch (error) {
    ElMessage.error('获取派单记录失败');
  }
}

const assignRepairer = async () => {
  if (!assignForm.repairerId) {
    ElMessage.warning('请输入维修师傅ID')
    return
  }

  try {
    await request({
      method: 'POST',
      url: '/repair/request/assign',
      data: {
        requestId: assignForm.requestId,
        repairerId: assignForm.repairerId
      }
    })
    
    ElMessage.success('派单成功')
    assignDialog.visible = false
    loadRequests()
    loadHistory()
  } catch (error) {
    ElMessage.error('派单失败')
  }
}

const downloadFile = (url: string) => {
  if (!url) {
    ElMessage.warning('没有可下载的附件')
    return
  }
  
  const link = document.createElement('a')
  link.href = url
  link.target = '_blank'
  link.download = url.split('/').pop() || 'attachment'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const showAssignDialog = (request: RepairRequest) => {
  currentRequest.value = request
  assignForm.requestId = request.id
  assignForm.serialNumber = request.serialNumber
  assignForm.repairerId = null
  assignDialog.visible = true
}

const showDispatchInfo = (request: RepairRequest) => {
  currentRequest.value = request
  infoDialog.visible = true
}

const resetSearch = () => {
  searchParams.serialNumber = null
  searchParams.applicantId = null
  loadRequests()
}

const resetHistorySearch = () => {
  historySearchParams.serialNumber = null
  historySearchParams.applicantId = null
  historySearchParams.selectedStatus = null  // 清空用户选择的状态
  loadHistory()  // 加载默认的三个状态
}

const calculateStats = () => {
  stats.pending = pendingAssignments.value.length
  stats.assigned = pendingAssignments.value.filter(r => r.status === '已分配').length
  stats.completed = pendingAssignments.value.filter(r => ['维修完毕', '已完成'].includes(r.status)).length
}

const statusTagType = (status: string) => {
  switch (status) {
    case '待分配': return 'danger'
    case '已分配': return 'warning'
    case '维修完毕': return ''
    case '已完成': return 'success'
    default: return 'info'
  }
}

const handleTabChange = (tab: string) => {
  if (tab === 'history') {
    loadHistory()
  } else {
    loadRequests()
  }
}

const isImageFile = (url: string): boolean => {
  return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url)
}

onMounted(() => {
  loadRequests()
})
</script>

<style lang="scss" scoped>
/* 保持不变 */
.maintenance-wrapper {
  min-height: 100vh;
  padding: 1rem;
  box-sizing: border-box;
  background-color: #f0f2f5;
  display: flex;
  justify-content: center;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  color: #2c3e50;
}

.card-box {
  width: 100%;
  max-width: 100%;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.header {
  padding: 0.8rem 1.2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e6eaf0;
  background-color: #f7f9fc;
  h2 {
    font-weight: 600;
    font-size: 1.4rem;
    color: #333;
    user-select: none;
    margin: 0;
  }
  .stats {
    display: flex;
    gap: 8px;
    .el-tag {
      font-weight: 500;
      height: 28px;
      line-height: 28px;
      padding: 0 8px;
    }
  }
}

.filter-bar {
  padding: 0.8rem 1.2rem;
  background-color: #fafbfc;
  border-bottom: 1px solid #e6eaf0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  overflow-x: auto;
  white-space: nowrap;
  gap: 0.8rem;

  .el-form-item {
    margin-bottom: 0 !important;
    flex-shrink: 0;
    label {
      font-weight: 500;
      color: #606266;
      font-size: 0.9rem;
    }
    .input-short {
      width: 160px;
    }
  }

  .el-button {
    height: 32px;
    font-weight: 500;
    padding: 0 12px;
    flex-shrink: 0;
  }
}

.responsive-table-container {
  overflow-x: auto;
  background: #fff;
  padding: 0.8rem;
}

.custom-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 6px;
  font-size: 0.9rem;

  thead tr {
    background-color: #f5f7fa;
    color: #606266;
    font-weight: 600;
    user-select: none;
  }

  th, td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
  }

  th {
    font-size: 0.85rem;
  }

  tbody tr {
    background-color: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    transition: background-color 0.2s ease;

    &:hover {
      background-color: #f4f9ff;
    }
  }

  .truncate {
    max-width: 180px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .action-btns {
    display: flex;
    gap: 0.4rem;

    .el-button {
      padding: 0;
      width: 28px;
      height: 28px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
    }
  }
}

.no-attachment {
  color: #a9abb0;
  font-style: italic;
  user-select: none;
  font-size: 0.85rem;
}

.pagination-container {
  background-color: #fafbfc;
  padding: 0.8rem;
  border-top: 1px solid #e6eaf0;
  display: flex;
  justify-content: center;
}

.text-center {
  text-align: center;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.drawer-form {
  .el-form-item {
    margin-bottom: 1rem;

    label {
      font-weight: 500;
      color: #606266;
      font-size: 0.9rem;
    }
  }

  .submit-btn {
    width: 100%;
    font-weight: 500;
    height: 36px;
  }
}

@media (max-width: 1200px) {
  .filter-bar {
    gap: 0.6rem;
    
    .input-short {
      width: 140px;
    }
  }
  
  .custom-table {
    font-size: 0.85rem;
    
    th, td {
      padding: 6px 8px;
    }
  }
}

@media (max-width: 992px) {
  .header {
    padding: 0.6rem 1rem;
    
    h2 {
      font-size: 1.2rem;
    }
  }
  
  .filter-bar {
    padding: 0.6rem 1rem;
  }
  
  .responsive-table-container {
    padding: 0.6rem;
  }
}
.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 0.2s ease;
  margin-right: 4px;
  vertical-align: middle;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.thumbnail-download {
  display: inline-block;
  width: 0;
  height: 0;
  overflow: hidden;
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid #ddd;
}

.image-popover {
  padding: 0 !important;
  background-color: transparent !important;
  box-shadow: none !important;
  border: none !important;
}

.preview-img {
  width: 300px; // 放大图片
  height: auto;
  max-height: 400px;
  display: block;
  object-fit: contain;
  border: none;
  border-radius: 0;
  background: transparent;
}

.thumbnail-download {
  display: none; // 你也可以用按钮代替
}
</style>